package ua.org.enginer.managers {
	
	import flash.events.EventDispatcher;
	import flash.events.TimerEvent;
	import flash.utils.Dictionary;
	import flash.utils.Timer;
	
	import mx.collections.ArrayCollection;
	import mx.managers.CursorManager;
	import mx.messaging.Channel;
	import mx.messaging.ChannelSet;
	import mx.messaging.channels.AMFChannel;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.remoting.RemoteObject;
	
	[Event(name="result", type="mx.rpc.events.ResultEvent")]
	
	public class RichAMFServiceManager extends EventDispatcher {
		
		private var requests:Dictionary = new Dictionary()
		//private var requestsFromBilling:Dictionary = new Dictionary()
		
		private var timer:Timer
		
		public var useDomainLogic:Boolean// = true
		public var useBusyCursor:Boolean = true
		private var service:RemoteObject
		
		private static var instance:RichAMFServiceManager;
		public static function getInstance(domain:String):RichAMFServiceManager {
			if (!instance) {
				instance = new RichAMFServiceManager(domain);
			}
			return instance;
		}
		
		function RichAMFServiceManager(domain:String) {
			super()
			
			var url:String = "http://"+domain+"/amfphp/gateway.php"
			var chan:Channel = new AMFChannel(null, url)
			
			service = new RemoteObject(domain)
			
			service.channelSet = new ChannelSet();
            service.channelSet.addChannel(chan);
			
			service.source = "RichController"
			
			timer = new Timer(1000, 1)
			timer.addEventListener(TimerEvent.TIMER, onTimer)
		}
		
		//private var result:MultiFiltersArrayCollection
		private var resultClass:Class
		private var owner:Object
		private var errorAnswer:String
		
		
		public function select(table:String, resultHandler:Function, 
								query:String='', resultClass:Class=null,
								owner:Object=null):ArrayCollection {
			
			var request:Object = {
				id: Math.random(),//UIDUtil.createUID(),
				table: table,
				query: "SELECT * FROM `"+table+"` "+query,
				resultClass: resultClass,
				resultHandler: resultHandler,
				owner: owner,
				result: new ArrayCollection()
			}
			
			requests[request.id] = request
			
			if (timer.running) timer.reset();
			timer.start()
			
			return request.result
		}
		
		/*
		public function selectFromBilling(query:String, resultHandler:Function, 
								resultClass:Class=null,
								owner:Object=null):ArrayCollection {
			
			var request:Object = {
				id: Math.random(),//UIDUtil.createUID(),
				query: query,
				resultClass: resultClass,
				resultHandler: resultHandler,
				owner: owner,
				result: new ArrayCollection()
			}
			
			requestsFromBilling[request.id] = request
			
			if (timer.running) timer.reset();
			timer.start()
			
			return request.result
		}
		*/
		
		private function onTimer(event:TimerEvent):void {
			send()
		}
		private function send():void {
			service.addEventListener(ResultEvent.RESULT, onSelectResult)
			service.addEventListener(FaultEvent.FAULT, onFault)
			
			if (useBusyCursor) CursorManager.setBusyCursor()
			
			var forSend:Array = []
			
			for each(var request:Object in requests) {
				forSend.push({id: request.id, table: request.table, query: request.query})
			}
			service.query(forSend, useDomainLogic)
			/*
			forSend = []
			
			for each(var request:Object in requestsFromBilling) {
				forSend.push({id: request.id, table: request.table, query: request.query})
			}
			service.queryFromBilling(forSend)
			*/
		}
		
		protected function onSelectResult(event:ResultEvent):void {
			if (useBusyCursor) CursorManager.removeBusyCursor()
			
			event.target.removeEventListener(ResultEvent.RESULT, onSelectResult)
			
			var item:Object
			var request:Object
			//var result:ArrayCollection = new ArrayCollection()
			
			for each(var remoutResult:Object in event.result) {
				request = requests[remoutResult.id]
				
				if (!request) {
					////
					continue
				}
				
				
				for each (var o:Object in remoutResult.result) {
					if (request.resultClass) {
						item = new request.resultClass(o)
						//item.owner = owner ? owner : result
					}else 
						item = o
						
					item.owner = request.owner ? request.owner : remoutResult.result
					request.result.addItem(item)
				}
				
				if (request.resultHandler) {
					request.resultHandler.apply(this, [request.result])
					//resultHandler = null
				}
				
				delete requests[remoutResult.id]
			}
			/*
			dispatchEvent(new ResultEvent("result", false, true, result))
			*/
		}
		
		protected function onFault(event:FaultEvent):void {
			event.target.removeEventListener(FaultEvent.FAULT, onFault)
			if (useBusyCursor) CursorManager.removeBusyCursor()
			trace(event.fault.faultDetail)
			//dispatchEvent(new ResultEvent("result", false, true, event.target.result))
		}
	}
}